
#include "unixHeader.h"
#include "user.srpc.h"
#include "workflow/WFFacilities.h"
#include <workflow/WFTaskFactory.h>
#include <workflow/MySQLResult.h>
#include <workflow/MySQLMessage.h>

#include <iostream>
using std::cout;
using std::endl;
using std::string;

using namespace srpc;

static WFFacilities::WaitGroup wait_group(1);

void sig_handler(int signo)
{
	wait_group.done();
}

class UserSignupServiceImpl : public UserSignup::Service
{
public:

	void Signup(ReqSignup *request, RespSignup *response, 
                srpc::RPCContext *ctx) override
    {
        //服务器端的用户注册服务函数Signup被调用时，已经接收到了request
        //1. 解析请求
        string username = request->username();
        string password = request->password();
        cout << "username:" << username << endl;
        cout << "password:" << password << endl;

        //2. 对密码进行加密
        string salt("12345678");//这里应该是随机生成
        string encodedPassword(crypt(password.c_str(), salt.c_str()));
        cout << "mi wen:" << encodedPassword << endl;
        //将用户信息存储到数据库MySQL中
        string mysqlurl("mysql://root:1234@localhost");
        auto mysqlTask = WFTaskFactory::create_mysql_task(mysqlurl, 1, 
        [response](WFMySQLTask * mysqltask){
            //0. 对任务的状态进行检测
            int state = mysqltask->get_state();
            int error = mysqltask->get_error();
            if(state != WFT_STATE_SUCCESS) {
                printf("%s\n", WFGlobal::get_error_string(state, error));
                return;
            }
            //1. 检测SQL语句是否存在语法错误
            auto mysqlResp = mysqltask->get_resp();
            if(mysqlResp->get_packet_type() == MYSQL_PACKET_ERROR) {
                printf("ERROR %d: %s\n", mysqlResp->get_error_code(),
                       mysqlResp->get_error_msg().c_str());
                response->set_msg("Singup Failed");
                response->set_code(404);
                return;
            }
            using namespace protocol;
            MySQLResultCursor cursor(mysqlResp);
            if(cursor.get_cursor_status() == MYSQL_STATUS_OK) {
                //2. 成功写入数据库了
                printf("Query OK. %llu row affected.\n",cursor.get_affected_rows());
                response->set_msg("SUCCESS");   
                response->set_code(200);
            } else {
                response->set_msg("Singup Failed");
                response->set_code(404);
            }
        });
        string sql("INSERT INTO cloudisk.tbl_user(user_name, user_pwd) VALUES('");
        sql += username + "', '" + encodedPassword + "')";
        cout << "sql:\n" << sql << endl;
        mysqlTask->get_req()->set_query(sql);
        //通过ctx可以获取到服务器任务所在的序列
        ctx->get_series()->push_back(mysqlTask);
    }
};

int main()
{
	GOOGLE_PROTOBUF_VERIFY_VERSION;
	unsigned short port = 1412;
	SRPCServer server;

	UserSignupServiceImpl usersignup_impl;
	server.add_service(&usersignup_impl);

	server.start(port);
	wait_group.wait();
	server.stop();
	google::protobuf::ShutdownProtobufLibrary();
	return 0;
}
